﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using BGShell.Components;
using BGShell.Controls;

namespace BGShell.PowerShell.Controls
{
    internal sealed class ConsoleTabPage : BGShellTabPage, 
                                           IEditableTabPage, 
                                           IExitCodeTabPage,
                                           IZoomableTabPage
    {
        private ConsoleControl _ctl;
        private Int32 _exitCode;

        public ConsoleTabPage()
        {
            ConsoleControl = new ConsoleControl();
            Image = Resources.DefaultTabIcon;
        }

        public override void OpenAsync()
        {
            _ctl.OpenRunspaceAsync();
        }

        public override void CloseAsync()
        {
            if (_ctl.IsBackground)
            {
                RemovePage();
            }
            else
            {
                _ctl.CloseRunspaceAsync();
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ConsoleControl ConsoleControl
        {
            get { return _ctl; }
            private set
            {
                if (_ctl != value)
                {
                    if (_ctl != null)
                    {
                        _ctl.Closed -= OnClosed;
                        _ctl.IsBusyChanged -= OnIsBusyChanged;
                        _ctl.WindowTitleChanged -= OnWindowTitleChanged;

                        Controls.Remove(_ctl);
                    }

                    _ctl = value;

                    if (_ctl != null)
                    {
                        _ctl.Dock = DockStyle.Fill;

                        _ctl.Closed += OnClosed;
                        _ctl.IsBusyChanged += OnIsBusyChanged;
                        _ctl.WindowTitleChanged += OnWindowTitleChanged;

                        Text = _ctl.WindowTitle;
                        IsBusy = _ctl.IsBusy;
                        Controls.Add(_ctl);
                    }
                }
            }
        }

        public Int32 ExitCode
        {
            get { return _exitCode; }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (ConsoleControl != null))
            {
                ConsoleControl.Dispose();
                ConsoleControl = null;
            }

            base.Dispose(disposing);
        }

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);

            // disable drawing, only causes flicker

            RedrawHelper.SetRedraw(this, false);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        private void OnClosed(object sender, ConsoleControlClosedEventArgs e)
        {
            if (_ctl.IsBackground)
            {
                BGShellApplication.Current.Exit(e.ExitCode);
            }
            else
            {
                _exitCode = e.ExitCode;
                RemovePage();
                Dispose();
            }
        }

        private void OnIsBusyChanged(object sender, EventArgs e)
        {
            IsBusy = _ctl.IsBusy;
        }

        private void OnWindowTitleChanged(object sender, EventArgs e)
        {
            Text = _ctl.WindowTitle;
        }

        bool IEditableTabPage.CanCut
        {
            get { return _ctl.CanCut; }
        }

        bool IEditableTabPage.CanCopy
        {
            get { return _ctl.CanCopy; }
        }

        bool IEditableTabPage.CanPaste
        {
            get { return _ctl.CanPaste; }
        }

        bool IEditableTabPage.CanSelectAll
        {
            get { return true; }
        }

        void IEditableTabPage.Cut()
        {
            _ctl.Cut();
        }

        void IEditableTabPage.Copy()
        {
            _ctl.Copy();
        }

        void IEditableTabPage.Paste()
        {
            _ctl.Paste();
        }

        void IEditableTabPage.SelectAll()
        {
            _ctl.SelectAll();
        }

        float IZoomableTabPage.ZoomFactor
        {
            get { return _ctl.ZoomFactor; }
            set { _ctl.ZoomFactor = value; }
        }

        event EventHandler IZoomableTabPage.ZoomFactorChanged
        {
            add { _ctl.ZoomFactorChanged += value; }
            remove { _ctl.ZoomFactorChanged -= value; }
        }
    }
}